package Day_0225.DesignPattern;

/**
 * @author zxc
 * @date 2023/02/25 21:22
 **/
public class Classification_Of_DesignPatterns {
    public static void main(String[] args) {
        /**
         * 设计模式的分类
         * ===》
         * 1.创建型模式，共五种：
         * 1）工厂方法模式 ：
         * ===》
         *  简单来说，按照需求返回一个类型的实例。
         *  java.lang.Proxy#newProxyInstance()
         *  java.lang.Object#toString()
         *  java.lang.Class#newInstance()
         *  java.lang.reflect.Array#newInstance()
         *  java.lang.reflect.Constructor#newInstance()
         *  java.lang.Boolean#valueOf(String)
         *  java.lang.Class#forName()
         *
         * 2）抽象工厂模式 ：
         * ===》
         * Abstract factory（抽象工厂模式）：
         * java.util.Calendar#getInstance()
         * java.util.Arrays#asList()
         * java.util.ResourceBundle#getBundle()
         * java.sql.DriverManager#getConnection()
         * java.sql.Connection#createStatement()
         * java.sql.Statement#executeQuery()
         * java.text.NumberFormat#getInstance()
         * javax.xml.transform.TransformerFactory#newInstance()
         *
         * 3）单例模式（Singleton）：
         * ===》
         * 只允许一个实例。在 Effective Java中建议使用Emun.
         * java.lang.Runtime#getRuntime()
         * java.awt.Toolkit#getDefaultToolkit()
         * java.awt.GraphicsEnvironment#getLocalGraphicsEnvironment()
         * java.awt.Desktop#getDesktop()
         *
         * 4）建造者模式 ：
         * ===》
         *  主要用来简化一个复杂的对象的创建。这个模式也可以用来实现一个 Fluent Interface。
         *  java.lang.StringBuilder#append()
         *  java.lang.StringBuffer#append()
         *  java.sql.PreparedStatement
         *  javax.swing.GroupLayout.Group#addComponent()
         *
         * 5）原型模式（Prototype） ：
         * ===》
         *  使用自己的实例创建另一个实例。
         *  有时候，创建一个实例，然后再把已有实例的值拷贝过去，是一个很复杂的动作。
         *  所以，使用这个模式可以避免这样的复杂性。
         *  java.lang.Object#clone()
         *  java.lang.Cloneable
         *
         * 2.结构型模式，共七种：
         * 1）适配器模式 ：
         * ===》
         * java.util.Arrays#asList()
         * javax.swing.JTable(TableModel)
         * java.io.InputStreamReader(InputStream)
         * java.io.OutputStreamWriter(OutputStream)
         * javax.xml.bind.annotation.adapters.XmlAdapter#marshal()
         * javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal()
         *
         * 2）装饰器模式 ：
         * ===》
         * 为一个对象动态地加上一系列的动作，不需要因为这些动作的不同，而产生大量的继承类。
         * java.io.BufferedInputStream(InputStream)
         * java.io.DataInputStream(InputStream)
         * java.io.BufferedOutputStream(OutputStream)
         * java.util.zip.ZipOutputStream(OutputStream)
         * java.util.Collections#checkedList|Map|Set|SortedSet|SortedMap
         *
         * 3）代理模式 ：
         * ===》
         * 用一个简单的对象来代替一个复杂的对象。
         * java.lang.reflect.Proxy
         * RMI
         *
         * 4）外观模式 ：
         * ===》
         * 用一个简单的接口包装一组组件，接口，抽象或是子系统。
         * java.lang.Class
         * javax.faces.webapp.FacesServlet
         *
         * 5）桥接模式 ：
         * ===》
         * 把抽象和实现解耦，于是接口和实现可在完全独立开来。
         * （1）AWT (提供了抽象层映射于实际的操作系统)
         * （2）JDBC
         *
         * 6）组合模式 ：
         * ===》
         * 让使用者把单独的对象和组合对象混用。
         * javax.swing.JComponent#add(Component)
         * java.awt.Container#add(Component)
         * java.util.Map#putAll(Map)
         * java.util.List#addAll(Collection)
         * java.util.Set#addAll(Collection)
         *
         * 7）享元模式 ：
         * ===》
         * 有效率地存储大量的小对象。
         * java.lang.Integer#valueOf(int)
         * java.lang.Boolean#valueOf(boolean)
         * java.lang.Byte#valueOf(byte)
         * java.lang.Character#valueOf(char)
         *
         * 3.行为型模式，共十一种：
         * 1）策略模式 ：
         * ===》
         * 定义一组算法，并把其封装到一个对象中。
         * 然后在运行时，可以灵活的使用其中的一个算法。
         * java.util.Comparator#compare()
         * javax.servlet.http.HttpServlet
         * javax.servlet.Filter#doFilter()
         *
         * 2）模板方法模式 ：
         * ===》
         * 允许子类重载部分父类而不需要完全重写。
         * java.util.Collections#sort()
         * java.io.InputStream#skip()
         * java.io.InputStream#read()
         * java.util.AbstractList#indexOf()
         *
         * 3）观察者模式 ：
         * ===》
         * 允许一个对象向所有的侦听的对象广播自己的消息或事件。
         * java.util.EventListener
         * javax.servlet.http.HttpSessionBindingListener
         * javax.servlet.http.HttpSessionAttributeListener
         * javax.faces.event.PhaseListener
         *
         * 4）迭代子模式 ：
         * ===》
         * 提供一种一致的方法，来顺序遍历一个容器中的所有元素。
         * java.util.Iterator
         * java.util.Enumeration
         *
         * 5）责任链模式 ：
         * ===》
         * 把一个对象在一个链接传递直到被处理。
         * 在这个链上的所有的对象有相同的接口（抽象类）但却有不同的实现。
         * java.util.logging.Logger#log()
         * javax.servlet.Filter#doFilter()
         *
         * 6）命令模式 ：
         * ===》
         * 把一个或一些命令封装到一个对象中。
         * java.lang.Runnable
         * javax.swing.Action
         *
         * 7）备忘录模式 ：
         * ===》
         * 给一个对象的状态做一个快照。Date类在内部使用了一个long型来做这个快照。
         * java.util.Date
         * java.io.Serializable
         *
         * 8）状态模式 ：
         * ===》
         * 这个模式允许你可以在运行时很容易地根据自身内部的状态改变对象的行为。
         * java.util.Iterator
         * javax.faces.lifecycle.LifeCycle#execute()
         *
         * 9）访问者模式 ：
         * ===》
         * 作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作.
         * javax.lang.model.element.Element 和javax.lang.model.element.ElementVisitor
         * javax.lang.model.type.TypeMirror 和javax.lang.model.type.TypeVisitor
         *
         * 10）中介者模式 ：
         * ===》
         * 用来减少对象单的直接通讯的依赖关系。使用一个中间类来管理消息的方向。
         * java.util.Timer
         * java.util.concurrent.Executor#execute()
         * java.util.concurrent.ExecutorService#submit()
         * java.lang.reflect.Method#invoke()
         *
         * 11）解释器模式 ：
         * ===》
         * 一个语法解释器的模式。
         * java.util.Pattern
         * java.text.Normalizer
         * java.text.Format
         *
         *
         */


        /**
         * 设计模式的基本原则
         * ===》
         * 1.开放封闭原则（Open Close Principle）
         * ===》
         * 原则思想：
         * （1）尽量通过扩展软件实体来解决需求变化，而不是通过修改已有的代码来完成变化描述：
         * （2）一个软件产品在生命周期内，都会发生变化，
         *  既然变化是一个既定的事实，我们就应该在设计的时候尽量适应这些变化，以提高项目的稳定性和灵活性。
         * （3）优点 ：单一原则告诉我们，每个类都有自己负责的职责，里氏替换原则不能破坏继承关系的体系。
         *
         * 2.里氏代换原则（Liskov Substitution Principle）
         * ===》
         * 原则思想 ：
         * （1）使用的基类，可以在任何地方使用继承的子类，完美地替换基类。
         * （2）子类可以扩展父类的功能，但不能改变父类原有的功能。
         *  子类可以实现父类的抽象方法，但不能覆盖父类的非抽象方法，子类中可以增加自己特有的方法。
         * （3）优点：增加程序的健壮性，即使增加了子类，原有的子类还可以继续运行，互不影响。
         *
         * 3.依赖倒转原则（Dependence Inversion Principle）
         * （1）依赖倒置原则的核心思想是面向接口编程.
         * （2）依赖倒转原则要求我们在程序代码中传递参数时或在关联关系中，尽量引用层次高的抽象层类，
         * （3）这个是开放封闭原则的基础，具体内容是：对接口编程，依赖于抽象而不依赖于具体。
         *
         * 4.接口隔离原则（Interface Segregation Principle）
         * ===》
         * （1）使用多个隔离的接口，比使用单个接口要好。还是一个降低类之间的耦合度的意思，
         *  ===》
         *  其实设计模式就是一个软件的设计思想，从大型软件架构出发，为了升级和维护方便。所以上文中多次出现：降低依赖，降低耦合。
         *  例如：支付类的接口和订单类的接口，需要把这俩个类别的接口变成俩个隔离的接口
         *
         * 5.迪米特法则（最少知道原则）（Demeter Principle）
         * ===》
         * 原则思想：一个对象应当对其他对象有尽可能少地了解，简称类间解耦
         * （1）一个类尽量减少自己对其他对象的依赖，原则是低耦合，高内聚，只有使各个模块之间的耦合尽量的低，才能提高代码的复用率。
         * （2）优点：低耦合，高内聚。
         *
         * 6.单一职责原则（Principle of single responsibility）
         * （1）原则思想 ：一个方法只负责一件事情。
         * （2）描述 ：单一职责原则很简单，一个方法 一个类只负责一个职责，各个职责的程序改动，不影响其它程序。
         * （3）优点 ：降低类和类的耦合，提高可读性，增加可维护性和可拓展性，降低可变性的风险。
         *
         */
    }
}
